#include<vector>
#include<unistd.h>
#include <time.h>
#include"BlockQueue.hpp"
#include "Task.hpp"

using namespace std;

#define CONSUMER_NUM 1
#define PRODUCER_NUM 1

void *Consumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    // while(true)
    // {
    //     int ret = bq->Pop();
    //     cout << "Consumer get a message: " << ret << endl;
    //     sleep(1);
    // }

    while(true)
    {
        Task ret = bq->Pop();
        //ret.Run();
        ret();
        // usleep(10000);
        //sleep(1);
        cout << "Consumer get a message, result: " << ret.GetResult() << endl;
    }
}

void *Producer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    //for(int i = 0; i < 50; ++i)
    // int i = 0;
    // while(true)
    // {
    //     usleep(100000);
    //     bq->Push(i);
    //     cout << "Producer push a message: " << i++ << endl;
    // }
    //bq->WakeUp();

    int operLen = oper.size();
    sleep(3);
    while(true)
    {
        int data1 = rand() % 10 + 1;
        int data2 = rand() % 10;
        // int opera = rand() % operLen;
        // Task t(data1, data2, oper[opera]);        ///先定义，在下方的输出内容中需要用到
        Task t(data1, data2, oper[rand() % operLen]);
        bq->Push(t);
        cout << "Producer push, " << t.GetTask() << ", tid = " << pthread_self() <<endl;
        sleep(1);
    }
}

int main()
{
    srand(time(nullptr));
    BlockQueue<Task> *bq = new BlockQueue<Task>();        //记得加上()
    vector<pthread_t> c_tid;
    vector<pthread_t> p_tid;

    for(int i = 0; i < CONSUMER_NUM; ++i)
    {
        pthread_t tid;
        pthread_create(&tid, nullptr, Consumer, bq);
        c_tid.push_back(tid);
    }
    for(int i = 0; i < PRODUCER_NUM; ++i)
    {
        pthread_t tid;
        pthread_create(&tid, nullptr, Producer, bq);
        p_tid.push_back(tid);
    }

    for(pthread_t & tid: c_tid)
    {
        pthread_join(tid, nullptr);
    }
    cout << "c_tid wait over" << endl;
    for(pthread_t & tid: p_tid)
    {
        pthread_join(tid, nullptr);
    }
    cout << "c_tid wait over" << endl;

    delete bq;
    cout << "bq deleted" << endl;

    return 0;
}